home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / smpi.zip / README.TXT < prev    next >
Text File  |  1993-03-11  |  8KB  |  218 lines

  1. This sample program consists of two parts.  First, all the necessary
  2. source code is provided to compile a Win32 sample program that sends
  3. an IOCtl_SCSI_MINIPORT request with a custom ControlCode to the SCSI
  4. miniport driver.  Second, a detailed description is provided that
  5. explains what changes the driver writer has to make to a SCSI
  6. miniport driver to allow it to properly recognize and handle the
  7. corresponding IOCtl request from the Win32 sample program.
  8.  
  9. Part 1 - Win32 sample
  10.  
  11. The SCSI Miniport IOCtl sample, SMPI.C, demonstrates how a Win32
  12. application sends a user defined IOCtl Control Code to a SCSI
  13. miniport driver. This is a simple program that is composed of four
  14. steps.
  15.  
  16. Step 1, a handle is obtained to the SCSI miniport driver using the
  17. Win32 API, CreateFile.  The name of the file to be opened is
  18. \\.\Scsi0:.  As an alternative, a drive letter can be substituted for
  19. \\.\Scsi0: (e.g. - \\.\C:).  This will map to the appropriate SCSI
  20. miniport driver that is responsible for C:.
  21.  
  22. Step 2, the SRB_IO_CONTROL structure is filled out.  The following
  23. items must be completed :
  24.  
  25.      HeaderLength - must be the size of an SRB_IO_CONTROL structure
  26.      ControlCode - while strictly optional, this entry should be
  27.               considered mandatory.  The ControlCode value is used to
  28.               further sub-divide IOCTL_SCSI_MINIPORT requests.  The
  29.               contents of ControlCode are defined by the SCSI miniport
  30.               driver writer.
  31.      Length - the size of the data buffer immediately following the
  32.               SRB_IO_CONTROL structure.  If no additional data buffer
  33.               is used, then this must be set to 0.
  34.  
  35. The following items of the SRB_IO_CONTROL structure are optional :
  36.  
  37.      Signature - these 8 bytes are available to help prevent IOCtl
  38.               conflicts between various vendors
  39.      Timeout - indicates the minimum time in seconds before the
  40.               request has timed out.  There is no maximum Timeout for
  41.               IOCTL_SCSI_MINIPORT.  Note, for IOCTL_SCSI_PASS_THROUGH,
  42.               the maximum time out value is 108000 seconds (30 minutes).
  43.      ReturnCode - this entry is filled in by the SCSI miniport to
  44.               inform the Win32 application of the results of the
  45.               requested action.  The contents of ReturnCode are defined
  46.               by the SCSI miniport Driver writer.
  47.  
  48. In the SMPI.C sample, two customer defined ControlCodes are used,
  49. SMP_RETURN_3F and SMP_PRINT_STRING.  The first requires
  50. no additional data buffer.  The second requires that a contiguous
  51. data buffer be appended at the end of the SRB_IO_CONTROL structure. 
  52. The ControlCodes are defined by the SCSI miniport driver (see below).
  53.  
  54. Step 3, send the SRB_IO_CONTROL structure to the SCSI miniport driver
  55. via the DeviceIoControl Win32 API.  The dwIoControlCode must be
  56. IOCTL_SCSI_MINIPORT.  This particular dwIoControlCode is not
  57. currently defined in any of the Win32 SDK header files and must be
  58. defined in your own personal header file.  It is defined in the
  59. Windows NT DDK header file, NTDDSCSI.H.  Including a Windows NT
  60. DDK header file in a Win32 source file has been avoided strictly to
  61. demonstrate the ability to write a Win32 application that accesses a
  62. device driver without having the Windows NT DDK.
  63.  
  64. Step 4, close the handle to the SCSI miniport driver.
  65.  
  66. In SMPI.C, steps 2 and 3 are repeated to demonstrate the two
  67. ControlCodes, SMP_RETURN_3F and SMP_PRINT_STRING.  The
  68. first requires no extra data buffer and so 'length' is set to 0.  The
  69. second does require additional buffer space.  The value of 100 is
  70. used as it makes the buffer large enough to handle up to 100 bytes of
  71. data returned by the SCSI miniport driver.
  72.  
  73. When strings are manipulated via the _memXXX functions, the
  74. terminating null is not used.  When using strXXX commands, the
  75. terminating null is used.  strlen does not include the terminating
  76. null in it's total.
  77.  
  78. Part 2 - SCSI Miniport Driver
  79.  
  80. The SCSI miniport driver writer is free to define the ControlCode to
  81. any value.  Microsoft has provided a template for defining such
  82. values and the driver writer can use this template for determining
  83. their ControlCode values, but are not obligated to do so.  In this
  84. sample, SMP_RETURN_3F was defined using the template and
  85. SMP_PRINT_STRING was defined with a random number.
  86.  
  87. If the microsoft template is to be used, then the Windows NT DDK
  88. header file, DEVIOCTL.H, should be consulted before defining a new
  89. IOCtl.  Also, the "Kernel-mode Driver Design Guide" contains
  90. additional information on page B-12.  There are two documentation
  91. errors on this page. First, the bit pattern should be :
  92.  
  93.       bit(s)     purpose
  94.       ------     -------
  95.       0,1        Transfer type
  96.       2-12       Function Code
  97.       13         Customer bit
  98.       14,15      Required Access
  99.       16-30      Device type
  100.       31         Common bit
  101.  
  102. The second documentation error states that the Function Code values
  103. can be 0x00 to 0x7F for Microsoft defined IOCtls and 0x80 to 0xFF for
  104. user defined IOCtls.  This should be 0x000 to 0x7FF for Microsoft
  105. defined IOCtls and 0x800 to 0xFFF for user defined IOCtls.  The
  106. Function Code field defines the function and the Customer bit
  107. determines whether the function is defined by Microsoft or a
  108. customer.
  109.  
  110. The following should be added to the SCSI minport driver's header
  111. file :
  112.  
  113. //
  114. // IOCtl definitions
  115. //
  116.  
  117. //
  118. // Define the various device type values.  Note that values used by Microsoft
  119. // Corporation are in the range 0x0000 - 0x7FFF, and 0x8000 - 0xFFFF are
  120. // reserved for use by customers.
  121. //
  122.  
  123. #define IOCTL_SCSI_MINIPORT_IO_CONTROL  0x8001
  124.  
  125. //
  126. // Macro definition for defining IOCTL and FSCTL function control codes.
  127. // Note that function codes 0x000 - 0x7FF are reserved for Microsoft
  128. // Corporation, and 0x800 - 0xFFF are reserved for customers.
  129. //
  130.  
  131. #define RETURNCODE0x0000003F   0x850
  132.  
  133. #define SMP_RETURN_3F     CTL_CODE(IOCTL_SCSI_MINIPORT_IO_CONTROL, RETURNCODE0x0000003F, METHOD_BUFFERED, FILE_ANY_ACCESS)
  134. #define SMP_PRINT_STRING  0x80000001
  135.  
  136. PCHAR Signature="MyDrvr";
  137. PCHAR DrvrString="This string was placed in the data area by the SCSI miniport driver\n";
  138.  
  139. typedef struct {
  140.     SRB_IO_CONTROL sic;
  141.     UCHAR          ucDataBuffer[512];
  142. } SRB_BUFFER, *PSRB_BUFFER;
  143.  
  144. The following should be added to the SCSI miniport driver's source
  145. code :
  146.  
  147. #include <miniport.h>
  148. #include <devioctl.h>
  149. #include <ntddscsi.h>
  150. #include "mydriver.h"
  151.  
  152. and the following should be added to the SCSI miniport driver's
  153. StartIo routine :
  154.  
  155. case SRB_FUNCTION_IO_CONTROL:
  156.  
  157.     if (!memcmp(((PSRB_IO_CONTROL)(Srb->DataBuffer))->Signature,Signature,strlen(Signature))) {
  158.  
  159.         DebugPrint((1,"MyDriverStartIo: MiniportIOCtl not supported\n"));
  160.  
  161.         Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
  162.  
  163.         ScsiPortNotification(RequestComplete,
  164.                              CardPtr,
  165.                              Srb);
  166.         break;
  167.         }
  168.  
  169.  
  170.     DebugPrint((1,"MyDriverStartIo: Miniport IOCtl received\n"));
  171.  
  172.     DebugPrint((3,"MyDriverStartIo: Srb->DataBuffer->ControlCode = %Xh\n",
  173.                     ((PSRB_IO_CONTROL)(Srb->DataBuffer))->ControlCode));
  174.  
  175.     switch (((PSRB_IO_CONTROL)(Srb->DataBuffer))->ControlCode) {
  176.  
  177.         case SMP_RETURN_3F :
  178.  
  179.            Srb->SrbStatus = SRB_STATUS_SUCCESS;
  180.  
  181.            ((PSRB_IO_CONTROL)(Srb->DataBuffer))->ReturnCode =
  182.               (ULONG) 0x0000003FL;
  183.  
  184.            ScsiPortNotification(RequestComplete,
  185.                                 CardPtr,
  186.                                 Srb);
  187.            break;
  188.  
  189.         case SMP_PRINT_STRING :
  190.  
  191.            Srb->SrbStatus = SRB_STATUS_SUCCESS;
  192.  
  193.            DebugPrint((0,"%s",((PSRB_BUFFER)(Srb->DataBuffer))->ucDataBuffer));
  194.  
  195.            strcpy(((PSRB_BUFFER)(Srb->DataBuffer))->ucDataBuffer,DrvrString);
  196.  
  197.            ScsiPortNotification(RequestComplete,
  198.                                 CardPtr,
  199.                                 Srb);
  200.            break;
  201.  
  202.         default :
  203.  
  204.            DebugPrint((1,"MyDriverStartIo: MiniportIOCtl not supported\n"));
  205.  
  206.            Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
  207.  
  208.            ScsiPortNotification(RequestComplete,
  209.                                 CardPtr,
  210.                                 Srb);
  211.            break;
  212.  
  213.     } // end switch
  214.  
  215.     break;
  216.  
  217.  
  218.